#!/usr/bin/env python

'''
Created on Apr 12, 2010

This module is responsible for handling the RPC requests from the client.

There is only one "Exposed" function (exposed_authenticate) which takes
the root's password as an argument, and returns a pointer to the (Modules) Package. 
'''

import rpyc
from rpyc.utils.server import ThreadedServer
from Dependencies import pam
import Modules
import Servers

class AccessDenied(Exception):
    '''
    Custom Exception based on the "Exception" class.
    '''
    pass

class CustomService(rpyc.Service):
    '''
    Custom service based on the "rpyc.Service" class.
    '''

    def on_connect(self) :
        '''
        Actions to be taken when a client connect to this service.
        '''
        print "Connected"

    def on_disconnect(self) :
        '''
        Actions to be taken when a client disconnect from this service.
        '''
        print "Disconnected"

    def exposed_authenticate(self, rootPass) :
        '''
        exposed_authenticate(rootPass)
            Takes the root's password and authenticate it against PAM.
            Returns a pointer to the 'Modules' package if authentication succeeded
            Raise an "AccessDenied" Exception if authentication failed.
        '''

        # Authenticate the root account with the passed password, against PAM.
        if pam.authenticate('root', rootPass, 'lcp') :

            print 'Authentication Succeeded\n'

            # Give this connection all authorities.
            self._conn._config.update(dict(
            allow_all_attrs = True,
            allow_pickle = True,
            allow_getattr = True,
            allow_setattr = True,
            allow_delattr = True,
            import_custom_exceptions = True,
            instantiate_custom_exceptions = True,
            instantiate_oldstyle_exceptions = True,
            ))

            self.exposed_Modules = Modules
            self.exposed_Servers = Servers

        else :
            # Raise an exception if the authentication failed.
            print 'Authentication Failed\n'
            raise AccessDenied


def main():

    # Create a Threaded Server with our CustomService class.
    server = ThreadedServer(CustomService, port = 4444, hostname = "0.0.0.0")

    # Start the server.
    server.start()

if __name__ == '__main__':
    main()
